﻿#include "tcpclient2.h"

bool datachange_flag = false;
tcpclient2::tcpclient2(QObject *parent) : QObject(parent)
{
    qRegisterMetaType<Qt::GlobalColor>("Qt::GlobalColor"); // 注册Qt::GlobalColor类型
    qRegisterMetaType<QVector<double>>("QVector<double>"); // 注册QVector<double>类型
}

tcpclient2::~tcpclient2()
{
    disconnectnet();
    delete tcpSocket;
}

void tcpclient2::creattcpclient()
{
    tcpSocket = new QTcpSocket();
    m_save_file = new save_file();
    connect(tcpSocket, &QTcpSocket::connected,
            [=]()
            {
                m_save_file->openfile(filename); // 打开文件
                txtFd.open(QIODevice::Truncate | QIODevice::WriteOnly);
                emit connect_done();
                emit recivedone("connected", Qt::GlobalColor::darkGreen);
            });
    connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(disconnectnet()));
    connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(onReceive()));
    // connect(tcpSocket, &QTcpSocket::readyRead, this, &tcpclient2::read);
}

void tcpclient2::write(const char *data, qint64 len)
{
    tcpSocket->write(data, len);
}

#if 0
void tcpclient2::read()
{
    QByteArray buffer = tcpSocket->readAll();
    if(savedataflag == true) {
        m_save_file->writefile(&buffer);    //此处存包
    }
}

#else

void tcpclient2::read()
{
    m_dataPacket.data += tcpSocket->readAll();
    bool isOk = false;
    do
    {
        isOk = parsePacket(tcpSocket, &m_dataPacket);
    } while (isOk);
}

#endif

void tcpclient2::read_data()
{
    // emit recivedone(QString("收到字节数：%1").arg( tcpSocket->bytesAvailable()), Qt::GlobalColor::blue);
    QString strDisplay;
    char buffer[16839]; // dma有效数据 8144*4 + 39结构体数据
    QByteArray Read_Temp = tcpSocket->read(19239);

#if 0
//调试使用  本地存数据
    {
        // 生成文件名
        QString fileName = QString("data.bin");
        QFile file(fileName);

        // 打开文件
        // 打开文件以追加模式
        if (!file.open(QIODevice::Append | QIODevice::WriteOnly))
        {
            qWarning() << "Cannot open file for writing:" << fileName;
            return;
        }

        // 写入数据到文件
        file.write(Read_Temp);

        // 关闭文件
        file.close();
    }

#endif
    recvBuffer.buffer += Read_Temp;
    if (recvBuffer.buffer.length() >= recvBuffer.packetSize * 10)
    {
        QByteArray temp;
        while (recvBuffer.buffer.length() > 4)
        {
            temp.clear();
            temp.push_back(recvBuffer.buffer.at(0));
            temp.push_back(recvBuffer.buffer.at(1));
            temp.push_back(recvBuffer.buffer.at(2));
            temp.push_back(recvBuffer.buffer.at(3));
            recvBuffer.buffer.remove(0, 4);
            unsigned int header;
            memcpy(&header, temp.data(), sizeof(unsigned int));
            if (header == 0xa55ab55b)
            {
                recvBuffer.buffer.push_front(temp.at(3));
                recvBuffer.buffer.push_front(temp.at(2));
                recvBuffer.buffer.push_front(temp.at(1));
                recvBuffer.buffer.push_front(temp.at(0));
                break;
            }
        }
        if (recvBuffer.buffer.length() >= recvBuffer.packetSize * 10)
        {
            int pos = 0;
            while (recvBuffer.buffer.length() >= pos + recvBuffer.packetSize)
            {
                pack_Control_To_PC_Sonar_data packetTemp;
                memcpy(&packetTemp, recvBuffer.buffer.data() + pos, sizeof(pack_Control_To_PC_Sonar_data));
                pluseInfos.push_back(packetTemp);
                pos += recvBuffer.packetSize;
                qDebug() << "conenct receive packnum " << packetTemp.pluse_info.PacketNumber << "\n";
            }
            recvBuffer.buffer.remove(0, pos);
        }
    }

    if (/* DISABLES CODE */ (1))
    {                                         // 十六进制显示
        QString a = Read_Temp.toHex().data(); // 十六进制显示
        a = a.toUpper();                      // 转换为大写
        for (int i = 0; i < a.length(); i += 2)
        {
            QString st = a.mid(i, 2); // 返回一个字符串 从指定位置返回n个字符
            strDisplay += st;
            strDisplay += " "; // 每个字节中间的空格
        }
    }
    else
    { // 字符显示
        strDisplay = QString(Read_Temp);
    }
    // emit recivedone(QString("收到数据：%1").arg(strDisplay), Qt::GlobalColor::blue);
}
void tcpclient2::onReceive()
{
    read_data();
    if (pluseInfos.length() > 10)
    {
        QTextStream is(&txtFd);
        while (pluseInfos.length() > 0)
        {
            pack_Control_To_PC_Sonar_data info = pluseInfos.first();
            //  m_save_file->writefile((char*)&info, sizeof(info));
            m_save_file->writefile((char *)info.pluse_info.data, sizeof(int) * DMA_DATA_SIZE);
            pluseInfos.pop_front();
            // tset
            is << "PingNumber:" << info.pluse_info.PingNumber << "\n";
            is << "PacketTotal:" << info.pluse_info.PacketTotal << "\n";
            is << "PacketNumber:" << info.pluse_info.PacketNumber << "\n";
            is << "time:" << info.pluse_info.time << "\n";
            is << "position:" << info.pluse_info.position << "\n";
            is << "channnel_num:" << info.pluse_info.channnel_num << "\n";
            is << "data:\n";
            for (int i = 0; i < DMA_DATA_SIZE; i++)
            {
                is << info.pluse_info.data[i] << ",";
            }
            is << "\n\n";
            qDebug() << "connect saved packnum" << info.pluse_info.PacketNumber << "\n";
        }
    }
}


bool tcpclient2::parsePacket(QTcpSocket *socket, SocketPacket *packet) // 解包
{

    if (packet->data.count() > 41943040)
    { // 40 * 1024 * 1024
        packet->data.clear();
        packet->readdataheadflag = false;
        return false;
    }
    if (packet->readdataheadflag == false)
    { // 如果没读数据头
        if (packet->data.count() < sizeof(SonarDataHead))
        { // 如果小于数据头，直接返回
            return false;
        }
        memcpy(&SonarDataHead, (pack_Control_To_PC_Sonar_data *)packet->data.data(), sizeof(pack_Control_To_PC_Sonar_data)); // 取数据头
        if (SonarDataHead.Massage_Header == 0xa55ab55b)
        {
            //            packet->readdataheadflag = true;
            //            packet->length = SonarDataHead.DataLength;
            //            packet->data = packet->data.mid(sizeof(SonarDataHead.pluse_info));     //截取从数据头之后直到末尾的数据
            //        } else {
            //            emit recivedone("包头错误", Qt::GlobalColor::red);  //弹窗警告，数据头错误
            //            disconnectnet();    //断开连接
            //        }
            //    }
            //    //解析包长度
            //    if(packet->data.count() < SonarDataHead.DataLength) {     //剩下的数据不够一包数据长度
            //        return false;
            //    }
            // 数据到达一包数据长度
            memcpy(sonardatabuf, packet->data, sizeof(SonarDataHead)); // 取数据
            if (datachange_flag == false)
            {
                memcpy(tempsonardatabuf, packet->data, sizeof(SonarDataHead)); // 取数据放入临时存储区
                emit startdatachange(tempsonardatabuf);
                datachange_flag = true;
            }
            if (savedataflag == true)
            {
                // m_save_file->writefile((char*)&SonarDataHead, sizeof(SonarDataHead));    //此处存包头,保证一个包头跟一包数据
                m_save_file->writefile((char *)&sonardatabuf, sizeof(sonardatabuf)); // 此处存包
            }
            memset(&sonardatabuf, 0, sizeof(sonardatabuf)); // 清空缓冲区
            // 删除当前包数据
            packet->data.remove(0, SonarDataHead.DataLength); // 移除前SonarDataHead.DataLength字节
            memset(&SonarDataHead, 0, sizeof(SonarDataHead)); // 清空数据头
            packet->readdataheadflag = false;
            return true;
        }
    }
}

void tcpclient2::sendData(const QString &data)
{
    QByteArray buffer;
    if (HexSendtcpclient)
    {
        buffer = hexStrToByteArray(data);
    }
    else if (Asciitcpclient)
    {
        buffer = asciiStrToByteArray(data);
    }
    else
    {
        buffer = data.toLatin1();
    }
    tcpSocket->write(buffer);
}

void tcpclient2::setfilename(QString name)
{
    QString DateTime = QDateTime::currentDateTime().toString("yyyy_MM_dd_hh_mm_ss_"); // 获取当前日期;
    filename = name + DateTime + "data.dat";
    txtFd.setFileName(name + DateTime + "dataText.txt");
}

void tcpclient2::setsavefileflag(bool flag)
{
    savedataflag = flag;
}

int tcpclient2::strHexToDecimal(const QString &strHex)
{
    bool ok;
    return strHex.toInt(&ok, 16);
}

char tcpclient2::convertHexChar(char ch)
{
    if ((ch >= '0') && (ch <= '9'))
    {
        return ch - 0x30;
    }
    else if ((ch >= 'A') && (ch <= 'F'))
    {
        return ch - 'A' + 10;
    }
    else if ((ch >= 'a') && (ch <= 'f'))
    {
        return ch - 'a' + 10;
    }
    else
    {
        return (-1);
    }
}

QByteArray tcpclient2::asciiStrToByteArray(const QString &str)
{
    QByteArray buffer;
    int len = str.length();
    QString letter;
    QString hex;
    for (int i = 0; i < len; i++)
    {
        letter = str.at(i);
        if (letter == "\\")
        {
            i++;
            letter = str.mid(i, 1);
            if (letter == "x")
            {
                i++;
                hex = str.mid(i, 2);
                buffer.append(strHexToDecimal(hex));
                i++;
                continue;
            }
            else if (letter == "N")
            {
                i++;
                hex = str.mid(i, 1);
                if (hex == "U")
                {
                    i++;
                    hex = str.mid(i, 1);
                    if (hex == "L")
                    { // NUL=0x00
                        buffer.append((char)0x00);
                        continue;
                    }
                }
                else if (hex == "A")
                {
                    i++;
                    hex = str.mid(i, 1);
                    if (hex == "K")
                    { // NAK=0x15
                        buffer.append(0x15);
                        continue;
                    }
                }
            }
            else if (letter == "S")
            {
                i++;
                hex = str.mid(i, 1);
                if (hex == "O")
                {
                    i++;
                    hex = str.mid(i, 1);
                    if (hex == "H")
                    { // SOH=0x01
                        buffer.append(0x01);
                        continue;
                    }
                    else
                    { // SO=0x0E
                        buffer.append(0x0E);
                        i--;
                        continue;
                    }
                }
                else if (hex == "T")
                {
                    i++;
                    hex = str.mid(i, 1);
                    if (hex == "X")
                    { // STX=0x02
                        buffer.append(0x02);
                        continue;
                    }
                }
                else if (hex == "I")
                { // SI=0x0F
                    buffer.append(0x0F);
                    continue;
                }
                else if (hex == "Y")
                {
                    i++;
                    hex = str.mid(i, 1);
                    if (hex == "N")
                    { // SYN=0x16
                        buffer.append(0x16);
                        continue;
                    }
                }
                else if (hex == "U")
                {
                    i++;
                    hex = str.mid(i, 1);
                    if (hex == "B")
                    { // SUB=0x1A
                        buffer.append(0x1A);
                        continue;
                    }
                }
            }
            else if (letter == "E")
            {
                i++;
                hex = str.mid(i, 1);
                if (hex == "T")
                {
                    i++;
                    hex = str.mid(i, 1);
                    if (hex == "X")
                    { // ETX=0x03
                        buffer.append(0x03);
                        continue;
                    }
                    else if (hex == "B")
                    { // ETB=0x17
                        buffer.append(0x17);
                        continue;
                    }
                }
                else if (hex == "O")
                {
                    i++;
                    hex = str.mid(i, 1);
                    if (hex == "T")
                    { // EOT=0x04
                        buffer.append(0x04);
                        continue;
                    }
                }
                else if (hex == "N")
                {
                    i++;
                    hex = str.mid(i, 1);
                    if (hex == "Q")
                    { // ENQ=0x05
                        buffer.append(0x05);
                        continue;
                    }
                }
                else if (hex == "M")
                { // EM=0x19
                    buffer.append(0x19);
                    continue;
                }
                else if (hex == "S")
                {
                    i++;
                    hex = str.mid(i, 1);
                    if (hex == "C")
                    { // ESC=0x1B
                        buffer.append(0x1B);
                        continue;
                    }
                }
            }
            else if (letter == "A")
            {
                i++;
                hex = str.mid(i, 1);
                if (hex == "C")
                {
                    i++;
                    hex = str.mid(i, 1);
                    if (hex == "K")
                    { // ACK=0x06
                        buffer.append(0x06);
                        continue;
                    }
                }
            }
            else if (letter == "B")
            {
                i++;
                hex = str.mid(i, 1);
                if (hex == "E")
                {
                    i++;
                    hex = str.mid(i, 1);
                    if (hex == "L")
                    { // BEL=0x07
                        buffer.append(0x07);
                        continue;
                    }
                }
                else if (hex == "S")
                { // BS=0x08
                    buffer.append(0x08);
                    continue;
                }
            }
            else if (letter == "C")
            {
                i++;
                hex = str.mid(i, 1);
                if (hex == "R")
                { // CR=0x0D
                    buffer.append(0x0D);
                    continue;
                }
                else if (hex == "A")
                {
                    i++;
                    hex = str.mid(i, 1);
                    if (hex == "N")
                    { // CAN=0x18
                        buffer.append(0x18);
                        continue;
                    }
                }
            }
            else if (letter == "D")
            {
                i++;
                hex = str.mid(i, 1);
                if (hex == "L")
                {
                    i++;
                    hex = str.mid(i, 1);
                    if (hex == "E")
                    { // DLE=0x10
                        buffer.append(0x10);
                        continue;
                    }
                }
                else if (hex == "C")
                {
                    i++;
                    hex = str.mid(i, 1);
                    if (hex == "1")
                    { // DC1=0x11
                        buffer.append(0x11);
                        continue;
                    }
                    else if (hex == "2")
                    { // DC2=0x12
                        buffer.append(0x12);
                        continue;
                    }
                    else if (hex == "3")
                    { // DC3=0x13
                        buffer.append(0x13);
                        continue;
                    }
                    else if (hex == "4")
                    { // DC2=0x14
                        buffer.append(0x14);
                        continue;
                    }
                }
            }
            else if (letter == "F")
            {
                i++;
                hex = str.mid(i, 1);
                if (hex == "F")
                { // FF=0x0C
                    buffer.append(0x0C);
                    continue;
                }
                else if (hex == "S")
                { // FS=0x1C
                    buffer.append(0x1C);
                    continue;
                }
            }
            else if (letter == "H")
            {
                i++;
                hex = str.mid(i, 1);
                if (hex == "T")
                { // HT=0x09
                    buffer.append(0x09);
                    continue;
                }
            }
            else if (letter == "L")
            {
                i++;
                hex = str.mid(i, 1);
                if (hex == "F")
                { // LF=0x0A
                    buffer.append(0x0A);
                    continue;
                }
            }
            else if (letter == "G")
            {
                i++;
                hex = str.mid(i, 1);
                if (hex == "S")
                { // GS=0x1D
                    buffer.append(0x1D);
                    continue;
                }
            }
            else if (letter == "R")
            {
                i++;
                hex = str.mid(i, 1);
                if (hex == "S")
                { // RS=0x1E
                    buffer.append(0x1E);
                    continue;
                }
            }
            else if (letter == "U")
            {
                i++;
                hex = str.mid(i, 1);
                if (hex == "S")
                { // US=0x1F
                    buffer.append(0x1F);
                    continue;
                }
            }
            else if (letter == "V")
            {
                i++;
                hex = str.mid(i, 1);
                if (hex == "T")
                { // VT=0x0B
                    buffer.append(0x0B);
                    continue;
                }
            }
            else if (letter == "\\")
            {
                // 如果连着的是多个\\则对应添加\对应的16进制0x5C
                buffer.append(0x5C);
                continue;
            }
            else
            {
                // 将对应的\[前面的\\也要加入
                buffer.append(0x5C);
                buffer.append(letter.toLatin1());
                continue;
            }
        }
        buffer.append(str.mid(i, 1).toLatin1());
    }
    return buffer;
}

QByteArray tcpclient2::hexStrToByteArray(const QString &str)
{
    QByteArray senddata;
    int hexdata, lowhexdata;
    int hexdatalen = 0;
    int len = str.length();
    senddata.resize(len / 2);
    char lstr, hstr;
    for (int i = 0; i < len;)
    {
        hstr = str.at(i).toLatin1();
        if (hstr == ' ')
        {
            i++;
            continue;
        }
        i++;
        if (i >= len)
        {
            break;
        }
        lstr = str.at(i).toLatin1();
        hexdata = convertHexChar(hstr);
        lowhexdata = convertHexChar(lstr);
        if ((hexdata == 16) || (lowhexdata == 16))
        {
            break;
        }
        else
        {
            hexdata = hexdata * 16 + lowhexdata;
        }
        i++;
        senddata[hexdatalen] = (char)hexdata;
        hexdatalen++;
    }
    senddata.resize(hexdatalen);
    return senddata;
}

void tcpclient2::connectnet(QString IP, quint16 PORT)
{
    // tcpSocket->bind(QHostAddress("192.168.37.1"));      // 删除
    tcpSocket->abort();
    tcpSocket->connectToHost(QHostAddress(IP), PORT);
}

void tcpclient2::disconnectnet()
{
    if (closing)
        return;
    closing = true;
    // 处理剩余数据
    if (tcpSocket->bytesAvailable() > 0)
    {
        QByteArray temp = tcpSocket->readAll();
        recvBuffer.buffer += temp;
        qDebug() << "disconnect receive size " << temp.length() << "\n";
    }
    if (recvBuffer.buffer.length() > 4)
    {
        QByteArray temp;
        while (recvBuffer.buffer.length() > 4)
        {
            temp.clear();
            temp.push_back(recvBuffer.buffer.at(0));
            temp.push_back(recvBuffer.buffer.at(1));
            temp.push_back(recvBuffer.buffer.at(2));
            temp.push_back(recvBuffer.buffer.at(3));
            recvBuffer.buffer.remove(0, 4);
            unsigned int header;
            memcpy(&header, temp.data(), sizeof(unsigned int));
            if (header == 0xa55ab55b)
            {
                recvBuffer.buffer.push_front(temp.at(3));
                recvBuffer.buffer.push_front(temp.at(2));
                recvBuffer.buffer.push_front(temp.at(1));
                recvBuffer.buffer.push_front(temp.at(0));
                break;
            }
        }
        int pos = 0;
        while (recvBuffer.buffer.length() >= pos + recvBuffer.packetSize)
        {
            pack_Control_To_PC_Sonar_data packetTemp;
            memcpy(&packetTemp, recvBuffer.buffer.data() + pos, sizeof(pack_Control_To_PC_Sonar_data));
            pluseInfos.push_back(packetTemp);
            pos += recvBuffer.packetSize;
            if (pluseInfos.length() > 10)
            {
                QTextStream is(&txtFd);
                while (pluseInfos.length() > 0)
                {
                    pack_Control_To_PC_Sonar_data info = pluseInfos.first();
                    //  m_save_file->writefile((char*)&info, sizeof(info));
                    m_save_file->writefile((char *)info.pluse_info.data, sizeof(int) * DMA_DATA_SIZE);
                    pluseInfos.pop_front();
                    // tset
                    is << "PingNumber:" << info.pluse_info.PingNumber << "\n";
                    is << "PacketTotal:" << info.pluse_info.PacketTotal << "\n";
                    is << "PacketNumber:" << info.pluse_info.PacketNumber << "\n";
                    is << "time:" << info.pluse_info.time << "\n";
                    is << "position:" << info.pluse_info.position << "\n";
                    is << "channnel_num:" << info.pluse_info.channnel_num << "\n";
                    is << "data:\n";
                    for (int i = 0; i < DMA_DATA_SIZE; i++)
                    {
                        is << info.pluse_info.data[i] << ",";
                    }
                    is << "\n\n";
                    qDebug() << "connect saved packnum" << info.pluse_info.PacketNumber << "\n";
                }
            }
        }
        recvBuffer.buffer.remove(0, pos);
    }
    if (pluseInfos.length() > 0)
    {
        QTextStream is(&txtFd);
        while (pluseInfos.length() > 0)
        {
            pack_Control_To_PC_Sonar_data info = pluseInfos.first();
            //  m_save_file->writefile((char*)&info, sizeof(info));
            m_save_file->writefile((char *)info.pluse_info.data, sizeof(int) * DMA_DATA_SIZE);
            pluseInfos.pop_front();
            // tset
            is << "PingNumber:" << info.pluse_info.PingNumber << "\n";
            is << "PacketTotal:" << info.pluse_info.PacketTotal << "\n";
            is << "PacketNumber:" << info.pluse_info.PacketNumber << "\n";
            is << "time:" << info.pluse_info.time << "\n";
            is << "position:" << info.pluse_info.position << "\n";
            is << "channnel_num:" << info.pluse_info.channnel_num << "\n";
            is << "data:\n";
            for (int i = 0; i < DMA_DATA_SIZE; i++)
            {
                is << info.pluse_info.data[i] << ",";
            }
            is << "\n\n";
            qDebug() << "connect saved packnum" << info.pluse_info.PacketNumber << "\n";
        }
    }
    qDebug() << "disconnect save done\n";
    // 断开连接
    tcpSocket->disconnectFromHost();
    emit disconnect_done();
    emit recivedone("服务器断开", Qt::GlobalColor::red);
    m_dataPacket.data.clear(); // 缓冲区清零
    recvBuffer.buffer.clear();
    datachange_flag = false;
    m_dataPacket.readdataheadflag = false; // 重新读取数据头标志位置false
    m_save_file->closefile();              // 关闭文件
    txtFd.close();
    closing = false;
}
